/*--------------------------------------------------------------------
File name: mb_parse_binary.h
Author: 刘长达      Version:   1.0     Date:
Description: 主要是具体的读取函数声明、交换函数
Contents:
 *--------------------------------------------------------------------*/

/*--------------------------------------------------------------------
 *                          文件更新和维护记录
 * Author:	刘长达
 * Date:	2019.11.10
 * Contents: 想明白具体的结构并创建
 * Date:	2019.11.14
 * Contents: 创建depth结构体的具体解析函数
 * Date:2019.12.6
 * Contents: 完成depth输出和解析的一系列工作。
 * Date:	2019.12.12
 * Contents: 完成输出和解析工作(depth和seabed)
 *
 *--------------------------------------------------------------------*/
#ifndef MB_PARSE_BINARY_H
#define MB_PARSE_BINARY_H
#include "struct_header.h"
#include"svm.h"
#include <fstream>
#include <stdlib.h>
#include <math.h>
#include <time.h>
//#include <iostream>
#include <assert.h>

#include <QDebug>
#include <QFile>
#include <QFileInfo>
#include <QFileDialog>
#include <QDataStream>
#include <QTextStream>
#include <QtMath>
#include <vector>
#include<Eigen/Eigen>
#include<Eigen/Dense>
using namespace Eigen;
using namespace std;


#define PI 3.1415926535898//M_PI
#define	MB_YES	        1
#define	MB_NO	        0
#define	MB_SUCCESS			1
#define	MB_FAILURE			0
#define cout qDebug()<<"["<<__FILE__<<":"<<__LINE__<<"]"
#define Malloc(type,n) (type *)malloc((n)*sizeof(type))
#define mb_swap_short(a) ( ((a & 0xff) << 8) | ((unsigned short)(a) >> 8) )
#define mb_swap_int(a) ( ((a) << 24) | \
                       (((a) << 8) & 0x00ff0000) | \
                       (((a) >> 8) & 0x0000ff00) | \
                        ((unsigned int)(a) >>24) )
typedef unsigned char	mb_u_char;
typedef signed char	mb_s_char;
typedef unsigned long long	mb_u_long;
typedef long long	mb_s_long;
typedef unsigned int mb_u_int;

class mb_parse_binary
{
public:
//-----------------------------数据解析-------------------------------
    static unsigned int depth_t, xyz_t, seabed_t, range_t, position_t, heading_t, attitude_t;
    struct mbsys_depth_struct depth;
    struct mbsys_xyz_struct xyz;
    struct mbsys_seabed_struct seabed;
    struct mbsys_range78_struct range78;
    struct mbsys_rangef_struct rangef;
    struct mbsys_heading_struct heading;
    struct mbsys_position_struct position;
    struct mbsys_runtime_struct runtime;
    struct mbsys_attitude_struct attitude;

    std::vector<mbsys_depth_struct> depth_arr;
    std::vector<mbsys_xyz_struct> xyz_arr;
    std::vector<mbsys_seabed_struct> seabed_arr;
    std::vector<mbsys_attitude_struct> attitude_arr;
    std::vector<mbsys_position_struct> position_arr;
    std::vector<mbsys_rangef_struct> rangef_arr;
    void func_get_binary(QString readfile);  // 获取二进制数据
    void func_print_binary(QString writefile);  // 打印二进制数据
    void func_print_depth(QString writefile);  // 打印按格式输出数据
    void func_print_seabed(QString writefile);
    void func_print_attitude(QString writefile);  // 打印按格式输出数据
    void func_print_postion(QString writefile);  // 打印按格式输出数据
    int mb_get_binary_short(void *buffer, void *ptr);
    int mb_get_binary_int(void *buffer, void *ptr);
    int mb_get_binary_float(void *buffer, void *ptr);
    int mb_get_binary_double(void *buffer, void *ptr);
    int mb_get_binary_long(void *buffer, void *ptr);
    int mb_swap_double(double *a);
    int mb_swap_float(float *a);
    int mb_swap_long(mb_s_long *a);
//-----------------------------数据改正及坐标归算-------------------------------
    struct raw_depth_struct depth_cor;
    struct raw_position_struct position_cor;
    struct raw_attitude_struct attitude_cor;
    struct raw_install_struct install_cor;
    struct raw_seabed_struct seabed_cor;
    std::vector<raw_depth_struct> depth_correct;
    std::vector<raw_position_struct> position_correct;
    std::vector<raw_attitude_struct> attitude_correct;
    std::vector<raw_install_struct> install_correct;
    std::vector<raw_seabed_struct> seabed_correct;
    std::vector<interval_position_attitude_struct> interval_correct;
    double GaussFilter[5] = {0.0545,0.2442,0.4026,0.2442,0.0545};
    void Data_Read(QString readfile);
    void Data_Read_Attitude(QString readfile);
    void Data_Read_Postion(QString readfile);
    void Data_Read_Seabed(QString readfile);
     void Data_Read_Range(QString readfile);
    int Gauss_Center(double longtitude);
    void GaussForward(double a, double f, double center, double bd, double ld, double &xi,  double &yi);
    void Correct_TS_Position();
    void GPS_Interpolation(double x0, double y0,double x1, double y1,int t10, int ti0,double &interval_x, double &interval_y);
    bool ATT_Interpolation(int depth_t,int attitude_t,std::vector<raw_attitude_struct>&attitude_correct,
                           std::vector<interval_position_attitude_struct>&interval_correct);
    int Position_TS(int ping,int first_ping,std::vector<interval_position_attitude_struct >&interval_correct,double vec[]);
    void Position_Beam(int ping,int first_ping,int beam_num, std::vector<raw_depth_struct>&depth_correct,
                       std::vector<interval_position_attitude_struct>&interval_correct);
    void Print_Interval(QString writefile);
    void Print_BS(QString writefile);
    int Depth_GaussFilter();
//-----------------------------底质分类-------------------------------
//    void BS_Classify_ISO(int c, int nc, int tn, int te, int tc, int nt,
//                         int ns,std::vector<bs_classify_struct>&bs_correct);
    struct bs_classify_struct bs_cor;
    std::vector<bs_classify_struct> bs_correct;
    void BS_Read(QString readfile);
public:
    void trainSVM(QString readfile,const std::string& modelFileName);		//训练数据
    void predictSVM(QString readfile, const std::string& modelFileName);	//数据预测
    void parse_command_line( char *input_file_name, char *model_file_name);
    void exit_input_error(int line_num);
    void read_problem(const char *filename);
private:
    void setParam();
    void readTestData(QString readfile);
    int SampleNum;
    std::list<svm_node*> dataList;  //list of features of all the samples
    std::list<double> typeList;  //list of type of all the samples
    struct svm_parameter param;		// set by parse_command_line
    struct svm_problem prob;		// set by read_problem
    struct svm_model *model;
    struct svm_node *x_space;
    //int cross_validation;
    int nr_fold;
//-----------------------------Kmeans------------------------------
public:
    enum InitMode
    {
        InitRandom,
        InitManual,
        InitUniform,
    };
    void  KMeans_First(int dimNum = 1, int clusterNum = 1, int iteriation = 100);
    void KMeans_After();
    void Cluster(const char* sampleFileName, const char* labelFileName);
    void Init(std::ifstream& sampleFile);
    void Init(double *data, int N);
    void Cluster(double *data, int N, int *Label);
    friend std::ostream& operator<<(std::ostream& out, mb_parse_binary& kmeans);
    void Data_Read_kmeans(QString readfile, double *data);
    void Data_Print_Kmeans(QString writefile, int *labels);
    void Kmeans_Cluster(QString readfile, int dim, int size, int cluster_num, int iteriation, QString writefile);
private:
    int m_dimNum;
    int m_clusterNum;
    double** m_means;
    int m_initMode;
    int m_maxIterNum;		// The stopping criterion regarding the number of iterations
    double m_endError;		// The stopping criterion regarding the error
    double GetLabel(const double* x, int* label);
    double CalcDistance(const double* x, const double* u, int dimNum);
};

#endif // MB_PARSE_BINARY_H
